//
//  File.cpp
//  trash
//
//  Created by Tai Yamaguchi on 2013/12/08.
//  Copyright (c) 2013年 personal constructor. All rights reserved.
//

#include "File.h"

//////////////////////////////////////////////////////////////
class IMInfo
{
public:
	virtual ~IMInfo(){}
	virtual const char* GetName() const = 0;
	virtual void PrintValue(const void* obj) const = 0;
}; // class IMInfo

struct IMInfoCollection
{
	IMInfo** data;
	size_t num;
	IMInfoCollection(IMInfo** d, size_t n)
	: data(d)
	, num (n)
	{
	}
	IMInfo* operator[](int i) const
	{
		FW_ASSERT(i<num);
		return data[i];
	}
	size_t size() const
	{
		return num;
	}
};

template<typename T> void TPrintValue(const T& v);
template<> void TPrintValue<int>(const int& v){ cout << v; }
template<> void TPrintValue<float>(const float& v){ cout << v; }
template<> void TPrintValue<std::string>(const std::string& v){ cout << v; }

template<typename T, typename MemT> class MInfo : public IMInfo
{
public:
	MemT T::*data;
	const char* name;
	MInfo(MemT T::*d, const char* n)
	: data(d), name(n)
	{
	}
	virtual const char* GetName() const{ return name; }
	virtual void PrintValue(const void* obj) const { TPrintValue(reinterpret_cast<const T*>(obj)->*data); }
};

template<typename T, typename MemT> IMInfo* CreateMIBase(MemT T::*data, const char* name)
{
	return new MInfo<T, MemT>(data, name);
}


#define _DECLARE(type, members)  \
typedef type self_t; \
static const IMInfoCollection& GetMemberInfo() \
{ \
static IMInfo* data[] = \
{ \
members \
}; \
static IMInfoCollection collection(data, (sizeof(data)/sizeof(data[0]))); \
return collection; \
}

#define _MEMBER(name)			CreateMIBase(&self_t::name, #name),

struct dumbData
{
	int		memberA;
	float	memberB;
	string	memberC;
	
	_DECLARE(dumbData,
			 _MEMBER(memberA)
			 _MEMBER(memberB)
			 _MEMBER(memberC)
			 )
};

void foo_2( FW_OBJECT_OPERATION operation )
{
	if( operation == FW_REGISTER_ON_INITIALIZE )
	{
		cout << "Hello, foo_2." << endl;
		dumbData t = { 1, 2.2f, "Hello" };
		const IMInfoCollection& members = t.GetMemberInfo();
		cout << "member counts = " << (int)members.size() << endl;
		for(int i=0; i<members.size(); i++)
		{
			cout << "[" << members[i]->GetName() << "]";
			members[i]->PrintValue(&t);
			cout << endl;
		}
	}
}
FW_REGISTER_FUNCTION( foo_2, 2 );

void foo_0( FW_OBJECT_OPERATION operation )
{
	if( operation == FW_REGISTER_ON_INITIALIZE )
	{
		cout << "Hello, foo_0." << endl;
		
		int32_t  a=0, b=1234;
		int32_t* pa=&a;
		int32_t* pb=&b;
		
		if(fw::AtomicCasPtr(&pa, pa, pb))
		{
			cout << "*pa = " << *pa << endl;
		}
		else
		{
			cout << "Cas failure.\n" << endl;
		}
		
	}
	else if( operation == FW_REGISTER_ON_DESTROY )
	{
		fw::Stack<int> stack;
		stack.Push(1);
		stack.Push(2);
		stack.Push(3);
		
		while (!stack.Empty())
		{
			int d;
			if(stack.Pop(&d))
			{
				cout << "stack value = " << d << endl;
			}
		}
		cout << endl;
		cout << "Goodbye, foo_0." << endl;
	}
}
FW_REGISTER_FUNCTION( foo_0, 0 ); // 関数名と任意のプライオリティ値. 高いほど優先して実行される.

void foo_1( FW_OBJECT_OPERATION operation )
{
	if( operation == FW_REGISTER_ON_INITIALIZE )
	{
		cout << "Hello, foo_1." << endl;
	}
	else if( operation == FW_REGISTER_ON_DESTROY )
	{
		cout << "Goodbye, foo_1." << endl;
	}
}
FW_REGISTER_FUNCTION( foo_1, 1 ); // 関数名と任意のプライオリティ値. 高いほど優先して実行される.


